/////////////////////////////////////////////////////////////////////////////
// Copyright(c) 2012-2015 purang All Rights Reserved
// Name:        thread_wrapper.h
// Purpose:     
// Author:      syy
// Modified by: 
// Created:     2014/1/3 14:17
// RCS-ID:      
// Licence:     
/////////////////////////////////////////////////////////////////////////////

#ifndef PR_SYSTEM_WRAPPERS_INTERFACE_THREAD_WRAPPER_H_
#define PR_SYSTEM_WRAPPERS_INTERFACE_THREAD_WRAPPER_H_

#include "../common_types.h"
#include "../typedefs.h"
#include "../core.h"

namespace qb
{
	// Object that will be passed by the spawned thread when it enters the callback
	// function.
#define ThreadObj void*

	// Callback function that the spawned thread will enter once spawned.
	// A return value of false is interpreted as that the function has no
	// more work to do and that the thread can be released.
	typedef bool(*ThreadRunFunction)(ThreadObj);
    typedef void(*ThreadAfterFunction)(ThreadObj);

	enum ThreadPriority
	{
		kLowPriority = 1,
		kNormalPriority = 2,
		kHighPriority = 3,
		kHighestPriority = 4,
		kRealtimePriority = 5
	};

	class S_CORE_EXPORT ThreadWrapper
	{
	public:
		enum {kThreadMaxNameLength = 64};

		virtual ~ThreadWrapper() {};

		// Factory method. Constructor disabled.
		//
		// func        Pointer to a, by user, specified callback function.
		// obj         Object associated with the thread. Passed in the callback
		//             function.
		// prio        Thread priority. May require root/admin rights.
		// thread_name  NULL terminated thread name, will be visable in the Windows
		//             debugger.
		static ThreadWrapper* CreateThread(ThreadRunFunction func,
			ThreadObj obj,
			ThreadPriority prio = kNormalPriority,
			const char* thread_name = 0);

		// Get the current thread's kernel thread ID.
		static uint32_t GetThreadId();

		// Non blocking termination of the spawned thread. Note that it is not safe
		// to delete this class until the spawned thread has been reclaimed.
		virtual void SetNotAlive() = 0;

		// Tries to spawns a thread and returns true if that was successful.
		// Additionally, it tries to set thread priority according to the priority
		// from when CreateThread was called. However, failure to set priority will
		// not result in a false return value.
		// TODO(henrike): add a function for polling whether priority was set or
		//                not.
		virtual bool Start(unsigned int& id) = 0;

		// Sets the threads CPU affinity. CPUs are listed 0 - (number of CPUs - 1).
		// The numbers in processor_numbers specify which CPUs are allowed to run the
		// thread. processor_numbers should not contain any duplicates and elements
		// should be lower than (number of CPUs - 1). amount_of_processors should be
		// equal to the number of processors listed in processor_numbers.
		virtual bool SetAffinity(const int* processor_numbers,
			const unsigned int amount_of_processors);

		// Stops the spawned thread and waits for it to be reclaimed with a timeout
		// of two seconds. Will return false if the thread was not reclaimed.
		// Multiple tries to Stop are allowed (e.g. to wait longer than 2 seconds).
		// It's ok to call Stop() even if the spawned thread has been reclaimed.
		virtual bool Stop() = 0;

		// The forced termination of a thread if needed
		virtual bool Stop(bool& force) = 0;

        // The final execution of the thread
        virtual void SetThreadAfterFunc(ThreadAfterFunction afterFunc) = 0;
	};

}  // namespace qb

#endif  // PR_SYSTEM_WRAPPERS_INTERFACE_THREAD_WRAPPER_H_
